package com.h6.crm.service.Impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.h6.crm.entity.Brand;
import com.h6.crm.entity.HrEmployee;
import com.h6.crm.entity.Project;
import com.h6.crm.entity.QuoteRecord;
import com.h6.crm.entity.SysUser;
import com.h6.crm.mapper.ProjectMapper;
import com.h6.crm.mapper.QuoteMapper;
import com.h6.crm.service.AttachmentService;
import com.h6.crm.service.BrandService;
import com.h6.crm.service.HrEmployeeService;
import com.h6.crm.service.QuoteService;
import com.h6.crm.util.Constant;
import com.h6.crm.util.pojo.ResultCode;
import com.h6.crm.util.pojo.ServiceException;
import com.h6.crm.util.pojo.dto.QuoteDetailDto;
import com.h6.crm.util.pojo.vo.QueryQuoteReocrdVO;
import com.h6.crm.util.pojo.vo.QuoteApprovalVO;
import com.h6.crm.util.pojo.vo.UpdateQuoteStatusVO;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

@Service
public class QuoteServiceImpl extends ServiceImpl<QuoteMapper, QuoteRecord> implements QuoteService {

    @Autowired
    QuoteMapper quoteMapper;

    @Autowired
    AttachmentService attachmentService;

    @Autowired
    ProjectMapper projectMapper;

    @Autowired
    HrEmployeeService employeeService;

    @Autowired
    BrandService brandService;

    @Override
    public QuoteDetailDto getQuoteRecordDetailById(Long id) {
        return quoteMapper.getQuoteRecordDetailById(id);
    }

    @Override
    public Boolean updateQuoteStatusById(Long id, UpdateQuoteStatusVO quoteVO, SysUser user) {
        QuoteRecord record = getById(id);
        if (ObjectUtil.isNull(record)) {
            throw new ServiceException(ResultCode.DATA_NOT_EXISTS);
        }
        record.setQuoteStatus(quoteVO.getQuoteStatus());
        return updateById(record);
    }

    @Override
    public Boolean quoteApproval(Long id, QuoteApprovalVO approvalVo) {
        QuoteRecord record = getById(id);
        if (ObjectUtil.isNull(record)) {
            throw new ServiceException(ResultCode.DATA_NOT_EXISTS);
        }
        if (StrUtil.equals(record.getQuoteStatus(), Constant.QUOTE_STATUS3)) {
            throw new ServiceException("报价已失效，无法进行审批");
        }
        if (!StrUtil.equals(record.getQuoteStatus(), Constant.QUOTE_STATUS4)) {
            throw new ServiceException("报价没有提交审批，无法进行审批");
        }
        record.setQuoteStatus(approvalVo.getQuoteStatus());
        return updateById(record);
    }

    @Override
    public Boolean quoteSubmit(Long id) {
        QuoteRecord record = getById(id);
        if (ObjectUtil.isNull(record)) {
            throw new ServiceException(ResultCode.DATA_NOT_EXISTS);
        }
        if (StrUtil.equals(record.getQuoteStatus(), Constant.QUOTE_STATUS3)) {
            throw new ServiceException("报价已失效，无法提交审批");
        }
        if (StrUtil.equals(record.getQuoteStatus(), Constant.QUOTE_STATUS4)) {
            throw new ServiceException("报价已提交审批，无需重复提交");
        }
        record.setQuoteStatus(Constant.QUOTE_STATUS4);
        return updateById(record);
    }

    @Override
    public Page<QuoteRecord> queryQuoteReocrdList(QueryQuoteReocrdVO vo) {
        QueryWrapper<QuoteRecord> queryWrapper = new QueryWrapper<QuoteRecord>();
        queryWrapper.ge(ObjectUtil.isNotNull(vo.getStartDate()), "FORMAT(QuoteDate, 'yyyy-MM-dd')", vo.getStartDate());
        queryWrapper.le(ObjectUtil.isNotNull(vo.getEndDate()), "FORMAT(QuoteDate, 'yyyy-MM-dd')", vo.getEndDate())
                .lambda()
                .eq(StrUtil.isNotBlank(vo.getQuoteStatus()), QuoteRecord::getQuoteStatus, vo.getQuoteStatus())
                .eq(ObjectUtil.isNotNull(vo.getBidderId()), QuoteRecord::getBidderId, vo.getBidderId())
                .eq(ObjectUtil.isNotNull(vo.getEntityId()), QuoteRecord::getEntityId, vo.getEntityId())
                .orderByDesc(QuoteRecord::getQuoteDate).orderByDesc(QuoteRecord::getId);
        if (StrUtil.isNotBlank(vo.getProjectName())) {
            List<Project> projectList = projectMapper.selectList(
                    new LambdaQueryWrapper<Project>().like(Project::getName, vo.getProjectName()));
            if (projectList.isEmpty()) {
                return new Page<QuoteRecord>(-1, 10);
            }
            queryWrapper.in("ProjectId", projectList.stream().map(Project::getId).collect(Collectors.toList()));
        }
        Page<QuoteRecord> quoteRecordPage = page(new Page<QuoteRecord>(vo.getPage(), vo.getPageSize()), queryWrapper);
        List<QuoteRecord> quoteRecords = quoteRecordPage.getRecords();
        Map<Long, Brand> brandCache = new HashMap<>();
        Map<Long, HrEmployee> employeeCache = new HashMap<>();
        Map<Long, Project> projectCache = new HashMap<>();
        quoteRecords.forEach(
                quote -> {
                    if (ObjectUtil.isNotNull(quote.getEntityId())) {
                        Brand brand = brandCache.get(quote.getEntityId());
                        if (ObjectUtil.isNull(brand)) {
                            brand = brandService.getById(quote.getEntityId());
                            brandCache.put(quote.getEntityId(), brand);
                            if (ObjectUtil.isNotNull(brand)) {
                                quote.setEntity(brand.getName());
                            }
                        } else {
                            quote.setEntity(brand.getName());
                        }
                    }
                    Project project = projectCache.get(quote.getProjectId());
                    if (ObjectUtil.isNull(project)) {
                        project = projectMapper.getProjectDetailById(quote.getProjectId());
                        if (ObjectUtil.isNotNull(project)) {
                            projectCache.put(quote.getProjectId(), project);
                            quote.setProjectName(project.getName());
                            quote.setClientName(project.getClientName());
                        }
                    } else {
                        quote.setClientName(project.getClientName());
                        quote.setProjectName(project.getName());
                    }
                    HrEmployee employee = employeeCache.get(quote.getBidderId());
                    if (ObjectUtil.isNull(employee)) {
                        employee = employeeService.getById(quote.getBidderId());
                        if (ObjectUtil.isNotNull(employee)) {
                            employeeCache.put(employee.getEmplId(), employee);
                            quote.setBidder(employee.getEmplName());
                        }
                    } else {
                        quote.setBidder(employee.getEmplName());
                    }
                });
        quoteRecordPage.setRecords(quoteRecords);
        return quoteRecordPage;
    }

    @Override
    public QuoteDetailDto getQuoteRecordDetailById2(Long id) {
        return quoteMapper.getQuoteRecordDetailById2(id);
    }

}
